import re
import os.path
import logging

from .iotype import IO_TYPE

class IO_Pin:  # 目前只适用于 PLC 引脚，其他IO格式... ??
    """ IO引脚 - 其文字表现形式为；PLC.MB2018.10 """
    regex_plc_format = re.compile(r"([a-z]+)\.([a-z]+)([\d\.]+)", re.IGNORECASE)  # PLC.MB2018.10, pdb.MB2023.0, tool.uuu2.0
    regex_sep_format = re.compile(r"([a-z]+)\.([a-z]+)\.(.*)", re.IGNORECASE)  # mfunction.code.out, tool.xxx.0
    regex_cnc_format = re.compile(r"([a-z]+)\.([\d\.]+)", re.IGNORECASE)  # cnc.3254.0, 
    # regex_dotsep_format = re.compile(r"(\w+)\.(\w+)\.(.*)", re.IGNORECASE)  # dac16.00.1.ch1.do3
    regex_cncparam_f = re.compile(r"([\w\[\]]+)", re.IGNORECASE)  # CNCPARAM, AXFEEDBACKPOS[X]

    def __init__(self, string=None):
        self.maintype = ""
        self.subtype = ""
        self.address = ""
        self.untype = False  # 用于标识其存在非定义TYPE

        if string is not None:
            self.loads(string)
        self._check_type()

    def __str__(self):
        """ so u could get the "PLC.MB2018.10" by str(IO_Pin) """
        return "{}.{}{}".format(self.maintype, self.subtype, self.address)

    def _check_type(self):
        if not self.maintype:  return True
        if self.subtype:
            type_name = self.maintype + "." + self.subtype
        else:
            type_name = self.maintype

        if not IO_TYPE.check_type(type_name):
            self.untype = True

    def loads(self, name: str):
        """ the interface to set the data """
        re_match = self.regex_plc_format.match(name)
        if not re_match:
            re_match = self.regex_sep_format.match(name)

        if re_match:
            self.maintype, self.subtype, self.address = re_match.groups()
        else:
            re_match = self.regex_cnc_format.match(name)
            if re_match:
                self.maintype, self.address = re_match.groups()
            else:
                re_match = self.regex_cncparam_f.match(name)
                if re_match:
                    self.address = re_match.groups()
                else:
                    raise Exception("IO_Pin --> Except! 无法解析的IO名称【{}】".format(name))
